package top.lixunda.commerce.common.core.config;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;

/**
 * @author Xumda
 * @version time:2019/11/21 11:58
 * <p>
 * feign进行网络请求之前对request进行拦截，添加所有请求头
 * 主要是sessionId
 */
@SuppressWarnings("Duplicates")
@Configuration
@Component
@Slf4j
public class FeignRequestInterceptor implements RequestInterceptor {

    private static final List<String> HEADER_NAMES = Arrays.asList("Cookie",
            "Host", "User-Agent", "Authorization");

    public FeignRequestInterceptor() {
        log.debug("Feign请求参数转发拦截器启动！");
    }

    @Override
    public void apply(RequestTemplate requestTemplate) {
        log.debug("Feign请求参数转发拦截器：开始克隆请求header！");
        //通过RequestContextHolder获取本地请求，需要同时配置RequestInterceptor是RequestAttributes可继承
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            log.error("错误！获取ServletRequestAttributes失败，克隆请求header失败，无法进行请求参数转发！请检查RequestInterceptor拦截器是否启动！");
            return;
        }
        //获取本地线程绑定的请求对象
        HttpServletRequest request = requestAttributes.getRequest();
        //给请求模板附加本地线程头部信息，主要是cookie信息
        Enumeration headerNames = request.getHeaderNames();
        log.debug("发现请求Headers: {}", headerNames);
        while (headerNames.hasMoreElements()) {
            String name = (String) headerNames.nextElement();
            if (name != null) {
                for (String headerName : HEADER_NAMES) {
                    if (headerName.equalsIgnoreCase(name)) {
                        requestTemplate.header(name, request.getHeader(name));
                        log.debug("添加了请求头信息： name:{}  value:{}", name, request.getHeader(name));
                    }
                }
            }
        }
//        // 当存在缓存的cookie时将缓存的cookie传递过去
//        // 解决第一次方位没有cookie，服务自己生成导致的session不一致问题
//        String cookie = (String) request.getAttribute(SpringSessionCookieSerializer.SET_COOKIE);
//        if (cookie != null && cookie.length() > 0) {
//            log.debug("添加了缓存的Set-Cookie请求头信息： name:COOKIE  value:{}", cookie);
//            requestTemplate.header(SpringSessionCookieSerializer.COOKIE, cookie);
//        }
    }
}
